package com.catmiw.funds.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import com.catmiw.funds.dao.FundMapper;
import com.catmiw.funds.dao.FundprofitMapper;
import com.catmiw.funds.dao.FundsplitMapper;
import com.catmiw.funds.dao.FundvalueMapper;
import com.catmiw.funds.dao.SplitOrProfitMapper;

import com.catmiw.funds.domain.Fund;
import com.catmiw.funds.domain.Profit;
import com.catmiw.funds.domain.Split;
import com.catmiw.funds.domain.SplitOrProfit;
import com.catmiw.funds.domain.Value;
import com.catmiw.funds.tool.DataLoader;
import com.catmiw.funds.tool.DateTool;

public class FundServiceImpl implements FundService {
	public List<Fund> selectAll() {
		SqlSession session=SessionFactory.getInstance().getSession();
		FundMapper cm=session.getMapper(FundMapper.class);

		List<Fund> old=cm.selectAll();
		session.close();
		
		return old;
	}
	
	public int insertAll(List<Fund> funds) {
		SqlSession session=SessionFactory.getInstance().getSession();
		
		FundMapper cm=session.getMapper(FundMapper.class);
		List<Fund> old=cm.selectAll();
		int count=0;
		for (Fund c:funds){
			if (c.getSetupdate()==null){
				c.setSetupdate(new Date());
			}
			if (old.contains(c)){
				cm.update(c);
			} else {
				cm.insert(c);
				count++;
			}
		}
		session.commit();
		session.close();
		
		return count;
	}

	private static void test(){
		SqlSession session=SessionFactory.getInstance().getSession();
		FundMapper cm=session.getMapper(FundMapper.class);
		List<Fund> old=cm.selectAll();
		for (Fund c:old){
			System.out.println(c);
		}
		session.close();
	}
	
	public void updateDiary(String code){
		SqlSession session=SessionFactory.getInstance().getSession();
		FundMapper cm=session.getMapper(FundMapper.class);
		Fund fund=cm.select(code);
		
		FundvalueMapper vm=session.getMapper(FundvalueMapper.class);
		FundsplitMapper sm=session.getMapper(FundsplitMapper.class);
		FundprofitMapper pm=session.getMapper(FundprofitMapper.class);
		Date max=vm.selectMaxDate(code);
		if (max==null||(max.compareTo(DataLoader.FUNDS_BEGINDATE))<0){
			max=DataLoader.FUNDS_BEGINDATE;
		} else {
			max=DateTool.dateAfterDays(max, 1);
		}
		
		Date now =new Date();
		if (DateTool.dateToString(now, "HH").compareTo("18")<0){
			now=DateTool.dateAfterDays(now, -1);
		}
		int day=DateTool.getDayOfWeek(now);
		if (day==1){
			now=DateTool.dateAfterDays(now, -2);
		} else if (day==7){
			now=DateTool.dateAfterDays(now, -1);
		}
		
		if (max.compareTo(now)>0)
			return;
		
		DataLoader.getValues(fund,max,now);
		
		List<Value> vs=fund.getValues();
		if (vs!=null&&vs.size()>0){
			for (Value v:vs){
				vm.insert(v);
			}
		}
		
		List<Split> ss=fund.getSplits();
		if (ss!=null&&ss.size()>0){
			for (Split v:ss){
				sm.insert(v);
			}
		}
		
		List<Profit> ps=fund.getProfits();
		if (ps!=null&&ps.size()>0){
			for (Profit v:ps){
				pm.insert(v);
			}
		}
		
		session.commit();
		session.close();
	}
	

	public Value getNewestValue(String code) {
		SqlSession session=SessionFactory.getInstance().getSession();
		FundvalueMapper vm=session.getMapper(FundvalueMapper.class);
		Date max=vm.selectMaxDate(code);
		session.commit();
		if (max==null)
			return null;
		
		Value v=new Value();
		v.setCode(code);
		v.setDate(max);
		
		v=vm.select(v);
		session.close();
		
		return v;
	}

	public List<Profit> selectAllProfit(String code) {
		SqlSession session=SessionFactory.getInstance().getSession();
		FundprofitMapper vm=session.getMapper(FundprofitMapper.class);
		List<Profit> ls=vm.selectByCode(code);
		
		return ls;
	}

	
	public List<Split> selectAllSplit(String code) {
		SqlSession session=SessionFactory.getInstance().getSession();
		FundsplitMapper vm=session.getMapper(FundsplitMapper.class);
		List<Split> ls=vm.selectByCode(code);
		
		return ls;
	}

	public List<Value> selectAllValue(String code) {
		SqlSession session=SessionFactory.getInstance().getSession();
		FundvalueMapper vm=session.getMapper(FundvalueMapper.class);

		List<Value> lv=vm.selectByCode(code);
		session.close();
		
		return lv;
	}

	public Value selectNearest(String code ,Date date) {
		SqlSession session=SessionFactory.getInstance().getSession();
		FundvalueMapper vm=session.getMapper(FundvalueMapper.class);

		Value v=new Value();
		v.setDate(date);
		v.setCode(code);
		
		v=vm.selectNearest(v);
		session.close();
		return v;
	}

	public List<SplitOrProfit> selectSplitOrProfit(String code) {
		SqlSession session=SessionFactory.getInstance().getSession();
		
		SplitOrProfitMapper vm=session.getMapper(SplitOrProfitMapper.class);
		List<SplitOrProfit> ls=vm.selectByCode(code);
		session.close();
		
		return ls;
	}

	public List<SplitOrProfit> selectSplitOrProfitPeriod(String code,
			Date fromdate, Date todate) {
		SqlSession session=SessionFactory.getInstance().getSession();
		SplitOrProfitMapper vm=session.getMapper(SplitOrProfitMapper.class);
		
		Map<String,Object> map=new HashMap<String,Object>();
		map.put("code",code);
		map.put("fromdate", fromdate);
		map.put("todate", todate);
		
		List<SplitOrProfit> ls=vm.selectPeriod(map);
		session.close();
		
		return ls;
	}

	public List<Value> selectValuePeriod(String code, Date fromdate, Date todate) {
		SqlSession session=SessionFactory.getInstance().getSession();
		FundvalueMapper vm=session.getMapper(FundvalueMapper.class);
		
		Map<String,Object> map=new HashMap<String,Object>();
		map.put("code",code);
		map.put("fromdate", fromdate);
		map.put("todate", todate);

		List<Value> lv=vm.selectPeriod(map);
		session.close();
		
		return lv;
	}

	public Value select(String code, Date date) {
		SqlSession session=SessionFactory.getInstance().getSession();
		FundvalueMapper vm=session.getMapper(FundvalueMapper.class);
		
		Value v=new Value();
		v.setCode(code);
		v.setDate(date);
		v=vm.select(v);
		
		session.close();
		
		return v;
	}
}
